﻿namespace CityProvince;

public partial class CityListView : Page {
    private static readonly DependencyPropertyKey UnknownCityItemsPropertyKey = DependencyProperty.RegisterReadOnly("UnknownCityItems", typeof(ExtendedObservableCollection<CityItem>), typeof(CityListView), new PropertyMetadata());
    public static readonly DependencyProperty UnknownCityItemsProperty = UnknownCityItemsPropertyKey.DependencyProperty;
    public const string UnknownCityFilePath = "Resources/Remains.txt";

    public ExtendedObservableCollection<CityItem> UnknownCityItems => (ExtendedObservableCollection<CityItem>)GetValue(UnknownCityItemsProperty);

    public CityListView() {
        SetValue(UnknownCityItemsPropertyKey, new ExtendedObservableCollection<CityItem>());
        // Ensure parent directory exists
        Directory.CreateDirectory(Path.GetDirectoryName(UnknownCityFilePath)!);
        if (!ConstantCollections.IsDataLoadedCompleted) {
            ConstantCollections.DataLoadedCompleted += ConstantCollectionsDataLoadedCompletedHandler;
        } else {
            this.SetLoadedOnceEventHandler((_, _) => {
                ConstantCollectionsDataLoadedCompletedHandler(this, new());
            });
        }
        InitializeComponent();
    }

    /// <summary>
    /// DataLoadedCompleted
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    /// <remarks>
    /// Running on task thread
    /// </remarks>
    private async void ConstantCollectionsDataLoadedCompletedHandler(object? sender, EventArgs e) {
        var cities = await Task.Run(() => {
            // File doesn't exist, populate with all cities
            if (!File.Exists(UnknownCityFilePath)) {
                return ConstantCollections.CityProvinceDict.Keys;
            }
            using var file = File.Open(UnknownCityFilePath, FileMode.OpenOrCreate, FileAccess.Read);
            using var reader = new StreamReader(file);
            return reader.ReadToEnd().Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
        });
        // Empty cities
        if (!cities.Any()) {
            cities = ConstantCollections.CityProvinceDict.Keys;
        }
        UnknownCityItems.AddRange(cities.Select(
            item => new CityItem(item)
        ).Shuffle());
    }

    private readonly Debounce UpdateRemainCityDebounce = new();

    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void DeleteCityItemClickHandler(object sender, RoutedEventArgs e) {
        e.Handled = true;
        var cityItems = CityItemListBox.SelectedItems.OfType<CityItem>().ToList();
        foreach (var item in cityItems) {
            UnknownCityItems.Remove(item);
        }
        SyncDataAsync();
    }

    private void SyncDataAsync() {
        UpdateRemainCityDebounce.RunAsync(async () => {
            var json = Dispatcher.Invoke(
                () => UnknownCityItems.Select(item => item.City)
            );
            await File.WriteAllLinesAsync(UnknownCityFilePath, json);
        });
    }

    /// <summary>
    /// 删除所有正确的选项
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void DeleteAllRightCityItemsClickHandler(object sender, RoutedEventArgs e) {
        e.Handled = true;
        UnknownCityItems.RemoveAll(item => item.IconColor == CityItem.CorrectColorBrush);
        SyncDataAsync();
    }
}
